package android.slc.box.core.ui;

import android.slc.box.core.notification.NotificationObserver;
import android.slc.box.core.property.SimpleWrapObjectProperty;
import de.saxsys.mvvmfx.ViewModel;
import javafx.beans.value.WeakChangeListener;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

public class ProtectedViewModelImpl implements ViewModel {

    private final Map<String, SimpleWrapObjectProperty<Object[]>> notificationHubs = new ConcurrentHashMap<>();


    @Override
    public void publish(String messageName, Object... payload) {
        if (notificationHubs.containsKey(messageName)) {
            SimpleWrapObjectProperty<Object[]> wrapObjectProperty = notificationHubs.get(messageName);
            wrapObjectProperty.setValuePlus(payload);
        }
    }

    @Override
    public void subscribe(String messageName, de.saxsys.mvvmfx.utils.notifications.NotificationObserver observer) {
        if (NotificationObserver.ensureProtectedNotificationObserver(observer)) {
            notificationHubs.computeIfAbsent(messageName, key -> {
                return new SimpleWrapObjectProperty<>(null, key);
            }).addListener((NotificationObserver) observer);
        }
    }

    public void subscribeWeak(String messageName, de.saxsys.mvvmfx.utils.notifications.NotificationObserver observer) {
        notificationHubs.computeIfAbsent(messageName, key -> {
            return new SimpleWrapObjectProperty<>(null, key);
        }).addListener(new WeakChangeListener<>((NotificationObserver) observer));
    }

    @Override
    public void unsubscribe(String messageName, de.saxsys.mvvmfx.utils.notifications.NotificationObserver observer) {
        if (NotificationObserver.ensureProtectedNotificationObserver(observer)) {
            notificationHubs.computeIfAbsent(messageName, key -> {
                return new SimpleWrapObjectProperty<>(null, key);
            }).removeListener((NotificationObserver) observer);
        }
    }

    @Override
    public void unsubscribe(de.saxsys.mvvmfx.utils.notifications.NotificationObserver observer) {
        if (NotificationObserver.ensureProtectedNotificationObserver(observer)) {
            notificationHubs.values().forEach(new Consumer<SimpleWrapObjectProperty<Object[]>>() {
                @Override
                public void accept(SimpleWrapObjectProperty<Object[]> objectSimpleWrapObjectProperty) {
                    objectSimpleWrapObjectProperty.removeListener((NotificationObserver) observer);
                }
            });
        }
    }

}
